package com.zdp.nio.selector;

import lombok.Builder;
import lombok.Data;
import lombok.SneakyThrows;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * Discard 服务器，接收到消息就直接丢弃。。
 */
@Data
@Builder
public class DiscardServer {
    @SneakyThrows
    public static void main(String[] args) {
        DiscardServer server = DiscardServer.builder().port(9905).build();
        server.start();
    }

    private int port ;

    public void start() throws IOException {
        // 1. 获取选择器
        Selector select = Selector.open();
        // 2. 获取 ServerSocketChannel 用于监听端口
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        // 2.1 绑定端口，就已经开始监听
        serverChannel.bind(new InetSocketAddress(port));
        System.out.println(String.format("服务启动，监听端口:{%d}",port));
        // 3. 注册 channel (监听 "接收到新连接"事件）
        serverChannel.register(select, SelectionKey.OP_ACCEPT);
        // 4. 阻塞监听
        while(select.select() > 0){
            Iterator<SelectionKey> iterator = select.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                // 5. 根据 事件的类型，来进行不同的操作
                if(key.isAcceptable()){
                    // 5.1 获取到 新连接
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel accept = channel.accept();
                    accept.configureBlocking(false);
                    // 将接收到的连接 注册到 选择器，监听其 read事件
                    accept.register(select,SelectionKey.OP_READ);
                }else if(key.isReadable()){
                    // 5.2 读取事件
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    // 读取通道的数据
                    int readLength = 0;
                    while((readLength = channel.read(byteBuffer)) > 0){
                        byteBuffer.flip();
                        System.out.println(String.format("丢弃数据 : %s",new String(byteBuffer.array(),0,byteBuffer.limit())));
                        byteBuffer.clear();
                    }
                    channel.close();
                }
                // 6. 移除事件
                iterator.remove();
            }
        }
        serverChannel.close();
        select.close();
    }

}
